'''
Created on Aug 15, 2011

@author: Andrzej
'''

import sys
from PyQt4 import QtCore, QtGui
from matplotlib.widgets import *

from PyDaq.Hardware.Daq328p import Daq328p
from PyDaq328pGuiUi import Ui_PyDaq328
from time import time
import numpy as np

class PyDaq328pGui(QtGui.QDialog):
    '''
    classdocs
    '''
    
    data = np.array([])
    time_axis = np.array([])
    t0   = []
    
    set_point = 7
    kp = 1;
    kd = 0
    ki = 0
    
    error = []
    
    
    def __init__(self, parent=None):
        '''
        Constructor
        '''
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_PyDaq328()
        self.ui.setupUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)
        
        self.Avr = Daq328p(7)
        
        self.GuiTimer = QtCore.QTimer()
        
        #Plot Configuration
        QtCore.QMetaObject.connectSlotsByName(self)
        
        self.fig = self.ui.TempPlot.figure
        self.ax = self.fig.add_subplot(111)
        
        #self.TempPlot = self.ax.plot(self.time,self.data)
        self.TempPlot = self.ax.plot([])        
        self.ui.TempPlot.axes.set_title("Oven Temperature")
        self.ui.TempPlot.axes.set_xlabel("Time")
        self.ui.TempPlot.axes.set_ylabel("Temperature [deg C]")                
        self.ui.TempPlot.axes.set_xlim([0, 100])
        self.ui.TempPlot.axes.set_ylim([-10, 250])
        self.ui.TempPlot.draw()        
        #self.ui.mplwidget.figure.get_axes().extend([0,10,12])  
        
        #=========================================================================================
        #SIGNALS and SLOTS
        # Start and Stop
        QtCore.QObject.connect(self.ui.ButtonStart,   QtCore.SIGNAL("clicked()"), self.Start)
        QtCore.QObject.connect(self.ui.ButtonStop,    QtCore.SIGNAL("clicked()"), self.Stop)
        QtCore.QObject.connect(self.ui.ButtonRead,    QtCore.SIGNAL("clicked()"), self.ReadAvrBuffer)
        QtCore.QObject.connect(self.ui.ButtonSaveData,QtCore.SIGNAL("clicked()"), self.SaveData)
        QtCore.QObject.connect(self.ui.ButtonLoadData,QtCore.SIGNAL("clicked()"), self.LoadData)
        # Text edit
        QtCore.QObject.connect(self.ui.AvrSend,       QtCore.SIGNAL("returnPressed()"), self.QueryAvr)        
        # Timer Signal 
        QtCore.QObject.connect(self.GuiTimer,         QtCore.SIGNAL("timeout()"), self.ReadHardwareData)
        # Slider Action
        QtCore.QObject.connect(self.ui.StovePowerPwm, QtCore.SIGNAL("valueChanged(int)"), self.SetStovePower)        
        
    def __del__(self):
        self.SetSSRPwm(0)
        self.Avr.close()
        
    def Start(self):
        self.t0 = time()
        timer_interval = 1000        
        self.GuiTimer.start(timer_interval)
        self.data = np.array([])
        self.time_axis = np.array([])
        log_text = 'Timer Started: %.1f, Timer Interval %.1f' % (self.t0, timer_interval)
        self.ui.LogList.addItem(log_text)
    
    def Stop(self):
        self.GuiTimer.stop()
        t_stop = time()
        duration = t_stop - self.t0
        log_text = 'Timer Stopped: %.1f, Timer Interval %.1f' % (t_stop, duration)
        self.ui.LogList.addItem(log_text)
    
    def SaveData(self):
        #filename = QFileDialog.getOpenFileName(self,
        #    'Open a data file', '.', 'CSV files (*.csv);;All Files (*.*)')
        
        filename = QtGui.QFileDialog.getSaveFileName()
        
        if filename:
            print "Saving to file: " + filename
            np.save(str(filename), [self.time_axis, self.data])
    
    def LoadData(self):
        filename = QtGui.QFileDialog.getOpenFileName()
        
        if filename:
            tmp = np.load(str(filename))
            self.time_axis = tmp[:][0]
            self.data      = tmp[:][1]            
            self.TempPlot = self.ax.plot(self.time_axis,self.data)        
            self.ui.TempPlot.draw()
    
        
    def ReadHardwareData(self):
        AdcData = self.Avr.GetADC(volt=1)
        if AdcData:
            self.data      = np.append(self.data, AdcData[0][1])
            self.time_axis = np.append(self.time_axis, time()-self.t0)
            
            self.error     = self.set_point - self.data[-1]*100
        
                
        #self.ui.mplwidget.axes.set_xlim([0, x_max])
        #self.ui.mplwidget.draw()
        #self.ui.ComList.addItem(str(val[0][1]))
        target_time = [0, 120, 210, 240, 300]
        target_temp = [30, 150, 183, 220, 150]
        #self.ui.TempPlot.axes.hold('on')        
        self.TempPlot = self.ax.plot(self.time_axis,self.data, target_time, target_temp,'-r')
        self.ui.TempPlot.axes.set_ylim([-10, 40])
        #self.ax.plot(self.time_axis,self.data)
        self.ui.TempPlot.draw()
    
    def ReadAvrBuffer(self):
        res = self.Avr.read()
        self.ui.AvrRead.append(res)
        self.ui.AvrRead.update() 
    
    def SetStovePower(self):
        new_pwm  = self.ui.StovePowerPwm.value()
        self.SetSSRPwm(float(new_pwm))
    
    def SetSSRPwm(self, pwm=0):
        SSR_MAX_POWER = 15625.0
        pwm = SSR_MAX_POWER*pwm/100.0
        cmd      = "ssr %.0f" % pwm
        log_text = 'Sending Avr cmd: ' + cmd
        self.ui.LogList.addItem(log_text)
        self.Avr.send(cmd)
                        
        
    def QueryAvr(self):
        """
        Copy command from the AvrSend edit line, send the command to hardware and 
        append response in the main terminal window
        """
        cmd = self.ui.AvrSend.text()
        res = self.Avr.query(cmd, expected_text="cmd>",delay=0.1)
        self.ui.AvrRead.append(res)
        self.ui.AvrRead.update()
        self.ui.AvrSend.clear()

        
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = PyDaq328pGui()
    myapp.show()
    sys.exit(app.exec_())